using System;
using System.ComponentModel;

namespace MathService
{
    public class LogItem : INotifyPropertyChanged
    {
        private event PropertyChangedEventHandler le_PropertyChanged;
        event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
        {
            add { le_PropertyChanged += value; }
            remove { le_PropertyChanged -= value; }
        }
        private void Invoke_PropertyChanged(string PropertyName = "State")
        {
            var lv_PropertyChangedHandlers = le_PropertyChanged;
            lv_PropertyChangedHandlers(this, new PropertyChangedEventArgs((PropertyName)));
        }

        public event EventHandler<EventArgs<object>> Changed;

        public void OnChanged(EventArgs<object> E)
        {
            var lv_Handler = Changed;
            if(lv_Handler != null) lv_Handler(this, E);
            Invoke_PropertyChanged();
        }

        private string f_Name;
        private object f_StateObj;

        public string Name
        {
            get { return f_Name; }
            set
            {
                if(f_Name == value) return;
                f_Name = value;
                Invoke_PropertyChanged("Name");
            }

        }

        public object State
        {
            get { return f_StateObj; }
            set
            {
                if(f_StateObj == value) return;
                if(f_StateObj is INotifyPropertyChanged)
                    ((INotifyPropertyChanged)f_StateObj).PropertyChanged -= ObjectChanged;
                f_StateObj = value;
                if(f_StateObj is INotifyPropertyChanged)
                    ((INotifyPropertyChanged)f_StateObj).PropertyChanged += ObjectChanged;
                OnChanged(value);
            }
        }

        public LogItem(string Name, object StateObj) : this(StateObj) { f_Name = Name; }
        public LogItem(object StateObj)
        {
            f_StateObj = StateObj;
            if(!(StateObj is INotifyPropertyChanged)) return;
            var o = (INotifyPropertyChanged)StateObj;
            o.PropertyChanged += ObjectChanged;
        }

        private void ObjectChanged(object Sender, PropertyChangedEventArgs E) { Invoke_PropertyChanged(); }

        public override string ToString()
        {
            var obj = f_StateObj;
            var name = f_Name;
            return string.IsNullOrEmpty(name)
                               ? (obj ?? "").ToString()
                               : string.Format("{0}:{1}", name, obj ?? "");
        }
    }
}